package com.yjzx.util.common.util.encrypt;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;
import java.util.Base64;

/**
 * @author yjzx
 * @date 2024/01/10
 * @description 加密接口
 */
public class AES {

    /**
     * 加密方式
     */
    private static final String KEY_ALGORITHM = "AES";
    /**
     * 数据填充方式
     */
    private static final String ALGORITHM_STR = "AES/CBC/PKCS5Padding";

    /**
     * 编码格式
     */
    static final String ENCODE = "UTF-8";

    static {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null){
            Security.addProvider(new BouncyCastleProvider());
        }
    }
    /**
     * 加密
     * @param originalContent 明文
     * @param encryptKey 秘钥
     * @param ivByte 向量
     * @return 加密后的字符串
     */
    public static String encrypt(String originalContent, String encryptKey,String ivByte) {

        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
            SecretKeySpec sKeySpec = new SecretKeySpec(encryptKey.getBytes(Charset.forName(ENCODE)), KEY_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, new IvParameterSpec(ivByte.getBytes(Charset.forName(ENCODE))));
            byte [] bytes = cipher.doFinal(originalContent.getBytes(Charset.forName(ENCODE)));
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解密
     * @param content 密文
     * @param aesKey 秘钥
     * @param ivByte 向量
     * @return 解密后的明文字符串
     */
    public static String decrypt(String content, String aesKey, String ivByte) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
            Key sKeySpec = new SecretKeySpec(aesKey.getBytes(Charset.forName(ENCODE)), KEY_ALGORITHM);
            // 初始化
            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIv(ivByte.getBytes(Charset.forName(ENCODE))));
            byte [] bytes = Base64.getDecoder().decode(content);
             return new String(cipher.doFinal(bytes),Charset.forName(ENCODE));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static AlgorithmParameters generateIv(byte[] iv) throws Exception {
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }

}